package main
import "fmt"
// import "io/ioutil"
import "time"
import (
	// "encoding/json"
	"net/http"
	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
  "gorm.io/driver/sqlite"
  "database/sql/driver"
	"log"
	"strings"
	"errors"
	"strconv"
)

var db *gorm.DB
var err error

// type User struct {
//   ID    uint   `json:"id"`
//   Name  string `json:"name"`
//   Email string `json:"email"`
//   Createdat    time.Time `json:"createdat"`
//   Updatedat    time.Time `json:"updatedat"`
// }

type MyTime time.Time

func (t *MyTime) UnmarshalJSON(data []byte) error {
	if string(data) == "null" {
		return nil
	}
	var err error
	//前端接收的时间字符串
	str := string(data)
	//去除接收的str收尾多余的"
	timeStr := strings.Trim(str, "\"")
	t1, err := time.Parse("2006-01-02", timeStr)
	*t = MyTime(t1)
	return err
}

func (t MyTime) MarshalJSON() ([]byte, error) {
	formatted := fmt.Sprintf("\"%v\"", time.Time(t).Format("2006-01-02"))
	return []byte(formatted), nil
}

func (t MyTime) Value() (driver.Value, error) {
	// MyTime 转换成 time.Time 类型
	tTime := time.Time(t)
	return tTime.Format("2006-01-02"), nil
}

func (t *MyTime) Scan(v interface{}) error {
	switch vt := v.(type) {
	case time.Time:
		// 字符串转成 time.Time 类型
		*t = MyTime(vt)
	default:
		return errors.New("类型处理错误")
	}
	return nil
}

func (t *MyTime) String() string {
	return fmt.Sprintf("hhh:%s", time.Time(*t).String())
}
type AuthUser struct{

  ID    uint   `json:"id"`
	// #     password = Column(String(128), nullable=False)
	// #     last_login = Column(DateTime)
	// #     is_superuser = Column(Boolean, nullable=False)
	// #     first_name = Column(String(30), nullable=False)
	// #     last_name = Column(String(30), nullable=False)
	// #     email = Column(String(254), nullable=False)
	// #     is_staff = Column(Boolean, nullable=False)
	// #     is_active = Column(Boolean, nullable=False)
	// #     date_joined = Column(DateTime, nullable=False)
	// #     username = Column(String(150), nullable=False)
	Username  string `json:"username"`
}
type Item struct{
    ID  uint   `json:"id"`
    Bh   string  `json:"bh"`//= Column(Text(30), index=True)
    Name  string  `json:"name"`//= Column(Text(30), nullable=False, index=True)
    Guige  string  `json:"guige"`//= Column(Text(30))
    Ct  uint  `json:"ct"`// = Column(Integer, nullable=False)
    Danwei string  `json:"danwei"`//= Column(Text(30), nullable=False)
    Image string  `json:"image"`//= Column(Text(100))
    Name_en string  `json:"name_en"`//= Column(Text(30))
    Beizhu string  `json:"beizhu"`//= Column(Text(30))
}
type UsePack struct{
    ID  uint   `json:"id"`
    Name  string  `json:"name"`//= Column(Text(30), nullable=False, index=True)
}
type Contact struct {
  	ID    uint   `json:"id"`
    Yonghu string  `json:"yonghu"`//= models.CharField(max_length=30,verbose_name="用户单位")#用户单位
    Addr string `json:"addr"`//= models.CharField(max_length=30,verbose_name="客户地址",null=True,blank=True)#用户单位
    Channels string `json:"channels"`//= models.CharField(max_length=30,verbose_name="通道配置",null=True,blank=True)#用户单位
    Yiqixinghao string `json:"yiqixinghao"`//=models.CharField(max_length=30,verbose_name="仪器型号")#仪器型号
    Yiqibh string `json:"yiqibh"`//=models.CharField(blank=False,unique=True,max_length=30,verbose_name="仪器编号")#仪器编号
    Baoxiang string `json:"baoxiang"`//=  models.CharField(max_length=30,verbose_name="包箱")#包箱
    Shenhe string `json:"shenhe"`//=  models.CharField(max_length=30,verbose_name="审核")#审核
    Yujifahuo_date MyTime `json:"yujifahuo_date"` //= models.DateField(verbose_name="预计发货时间")#预计发货时间
    Tiaoshi_date MyTime `json:"tiaoshi_date"`//= models.DateField(null=True,blank=True,verbose_name="调试时间",default=datetime.datetime.now)#预计发货时间
    Hetongbh string `json:"hetongbh"`//=models.CharField(unique=True,max_length=30,verbose_name="合同编号")#合同编号
    // dianqi string //=models.CharField(null=True,blank=True,max_length=30,verbose_name="电气")#合同编号
    // jixie string //=models.CharField(null=True,blank=True,max_length=30,verbose_name="机械")#合同编号
    // hongwai string //=models.CharField(null=True,blank=True,max_length=30,verbose_name="红外")#合同编号
    // redao string //=models.CharField(null=True,blank=True,max_length=30,verbose_name="热导")#合同编号
    Method string `json:"method"`//=models.FileField(null=True,blank=True,verbose_name="方法")
    Detail string `json:"detail"`//=models.TextField(null=True,blank=True,verbose_name="备注")
    Work_month MyTime `json:"work_month"`//= models.DateField(null=True,blank=True,verbose_name="工作月")#预计发货时间    
}
    // __tablename__ = 'todos_todo'
    // id = Column(Integer, primary_key=True)
    // text = Column(Text(30), nullable=False)
    // content = Column(Text(30), nullable=False)
    // completed = Column(Boolean) 
type Todo struct {
  ID    uint   `json:"id"`
  Text  string `json:"text"`
  Completed    bool `json:"completed"`
}
type Tabler interface {
  TableName() string
}

// TableName overrides the table name used by User to `profiles`
func (Todo) TableName() string {
  return "todos_todo"
}
func (Contact) TableName() string {
  return "parts_contact"
}
func (Item) TableName() string {
  return "parts_item"
}
func (UsePack) TableName() string {
  return "parts_usepack"
}
func (AuthUser) TableName() string {
  return "auth_user"
}
func main() {
	db, err = gorm.Open(sqlite.Open("./data.sqlite"), &gorm.Config{})
	//使用mysql, gorm.Open(“mysql”, “user:pwd@tcp(127.0.0.1:3306)/dbname?charset=utf8&parseTime=True&loc=Local”)
	if err != nil {
		log.Fatal("db connect error")
	}
	// defer db.Close()    //延时调用函数
	// db.AutoMigrate(&User{})

	r := gin.Default()
	r.SetTrustedProxies([]string{"127.0.0.1"})
	r.StaticFS("/static", http.Dir("./static"))
	r.GET("/", func(c *gin.Context) {
		c.Redirect(http.StatusMovedPermanently, "/static/index.html")
	})
	r.GET("/rest/Contact/", get_contact)
	r.POST("/rest/Contact/", post_contact)          
	r.PUT("/rest/Contact/", put_contact)         
	r.DELETE("/rest/Contact/", delete_contact)

	r.GET("/rest/UsePack/", get_usepack)

	r.GET("/rest/Item/", get_item)
	r.POST("/rest/Item/", post_item)          
	r.PUT("/rest/Item/", put_item)         
	r.DELETE("/rest/Item/", delete_item)

	r.GET("/rest/view_user/", get_users)

	r.GET("/rest/Todo/", get_todos)          
	r.POST("/rest/Todo/", post_todos)          
	r.PUT("/rest/Todo/:id", put_todos)         
	r.DELETE("/rest/Todo/:id", delete_todos)         
	r.GET("/rest/sql/", get_sql)          

	// r.GET("/users", get_users)          //获取所有用户
	// r.GET("/users/:id", get_user)       //根据id获取用户
	// r.POST("/users", post_user)         //保存新用户
	// r.PUT("/users/:id", put_user)     //根据id更新用户
	// r.DELETE("/users/:id", delete_user)  //根据id删除用户
	_ = r.Run(":8000")
}
type Contacts struct {
    total string `json:"total"`
    user   string `json:"user"`
    CreatedAt time.Time`json:"CreatedAt"`
}
func get_users(c *gin.Context) {
	var users []AuthUser
	var total  int64
	db.Find(&users).Count(&total)
	c.JSON(200, gin.H{"total": total,"data":users,"success":true})	
}
func post_item(c *gin.Context) {
	var user Item
	_ = c.BindJSON(&user) 	//绑定一个请求主体到一个类型
	db.Create(&user)
	c.JSON(200, user)
}
func put_item(c *gin.Context) {

}
func delete_item(c *gin.Context) {

}
func get_item(c *gin.Context) {
	var users []Item
	start, err := strconv.Atoi(c.Query("start"))
	if err != nil {
		start=0
	}
	limit, err := strconv.Atoi(c.Query("limit"))
	if err != nil {
		limit=10
	}
	search:="%"+c.Query("query")+"%"
 
	var total  int64
	db.Where("name like ? ", search).Find(&users).Count(&total)
	db.Limit(limit).Offset(start).Order("id desc").Where("name like ? ", search).Find(&users)
 	tmp:=fmt.Sprintf("start=%d limit=%d search=%s  total=%d",start,limit,search,total)
	log.Println(tmp)
	if err != nil {
		c.JSON(200, gin.H{"success": false})	
	}else{
		c.JSON(200, gin.H{"total": total,"data":users,"user":""})	
	}
	
}

func post_contact(c *gin.Context) {
	var user Contact
	_ = c.BindJSON(&user) 	//绑定一个请求主体到一个类型
	db.Create(&user)
	c.JSON(200, user)
}
func put_contact(c *gin.Context) {

}
func delete_contact(c *gin.Context) {

}
func get_usepack(c *gin.Context) {
	var users [] UsePack
	contact, err := strconv.Atoi(c.Query("contact"))
	if err != nil {
		contact=0
	}
	db.Where("contact_id= ?", contact).Find(&users)
	if err != nil {
		c.JSON(200, gin.H{"success": false})	
	}else{
		c.JSON(200, gin.H{"data":users})	
	}
	
}
func get_contact(c *gin.Context) {
	var users []Contact
	start, err := strconv.Atoi(c.Query("start"))
	if err != nil {
		start=0
	}
	limit, err := strconv.Atoi(c.Query("limit"))
	if err != nil {
		limit=10
	}
	search:="%"+c.Query("search")+"%"
	baoxiang:="%"+c.Query("baoxiang")+"%"
  tmp:=fmt.Sprintf("start=%d limit=%d search=%s baoxiang=%s",start,limit,search,baoxiang)
	log.Println(tmp)
	var total  int64
	// db.Where("(yiqibh like ? or yonghu like ? or hetongbh like ?) and baoxiang like ?", search,search,search,baoxiang).Find(&users).Count(&total)
	db.Model(&Contact{}).Where("(yiqibh like ? or yonghu like ? or hetongbh like ?) and baoxiang like ?", search,search,search,baoxiang).Count(&total)
	db.Limit(limit).Offset(start).Order("yujifahuo_date desc").Where("(yiqibh like ? or yonghu like ? or hetongbh like ?) and baoxiang like ?", search,search,search,baoxiang).Find(&users)

	if err != nil {
		c.JSON(200, gin.H{"success": false})	
	}else{
		c.JSON(200, gin.H{"total": total,"data":users,"user":""})	
	}
	
}

func get_sql(c *gin.Context) {
	cmd := c.Query("cmd")
	fmt.Println(cmd)
	db.Exec(cmd)
	c.JSON(200, "success")
}
func get_todos(c *gin.Context) {
	var users []Todo
	db.Find(&users)
	c.JSON(200, users)
}

// func get_users(c *gin.Context) {
// 	var users []User
// 	db.Find(&users)
// 	c.JSON(200, users)
// }

// func get_user(c *gin.Context) {
// 	id := c.Params.ByName("id")
// 	var user User
// 	db.First(&user, id)
// 	if user.ID == 0 {
// 		c.JSON(404, gin.H{"message": "user not found"})
// 		return
// 	}
// 	c.JSON(200, user)
// }
func post_todos(c *gin.Context) {
	var user Todo
	_ = c.BindJSON(&user) 	//绑定一个请求主体到一个类型
	db.Create(&user)
	c.JSON(200, user)
}
func put_todos(c *gin.Context) {
	id := c.Params.ByName("id")
	var user Todo
	db.First(&user, id)
	if user.ID == 0 {
		c.JSON(404, gin.H{"message": "todo not found"})
		return
	} else {
		_ = c.BindJSON(&user)
		db.Save(&user)
		c.JSON(200, user)
	}
}
func delete_todos(c *gin.Context) {
	id := c.Params.ByName("id")
	var user Todo
	db.First(&user, id)
	if user.ID == 0 {
		c.JSON(404, gin.H{"message": "todo not found"})
		return
	} else {
		_ = c.BindJSON(&user)
		db.Delete(&user)
		c.JSON(200, gin.H{"id":user.ID,"message": "delete success"})
	}
}
// func post_user(c *gin.Context) {
// 	// body, _ := ioutil.ReadAll(c.Request.Body)
//   //  println(string(body))
// 	var user User
// 	_ = c.BindJSON(&user) 	//绑定一个请求主体到一个类型
// 	db.Create(&user)
// 	c.JSON(200, user)
// }

// func put_user(c *gin.Context) {
// 	id := c.Params.ByName("id")
// 	var user User
// 	db.First(&user, id)
// 	if user.ID == 0 {
// 		c.JSON(404, gin.H{"message": "user not found"})
// 		return
// 	} else {
// 		_ = c.BindJSON(&user)
// 		db.Save(&user)
// 		c.JSON(200, user)
// 	}
// }

// func delete_user(c *gin.Context) {
// 	id := c.Params.ByName("id")
// 	var user User
// 	db.First(&user, id)
// 	if user.ID == 0 {
// 		c.JSON(404, gin.H{"message": "user not found"})
// 		return
// 	} else {
// 		_ = c.BindJSON(&user)
// 		db.Delete(&user)
// 		c.JSON(200, gin.H{"message": "delete success"})
// 	}
// }